package tencent_game_client;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import org.json.JSONObject;

import util.JsonUtil;

public class Client  {
	String serverip;
	int port;
	String usage[]=new String[]{
			"Usage:",
			"登录服务器。例如: login [username]",
			"查看在线用户信息，包括用户名，当前状态，得分等。例如: info [all | username]",
			"发起一个战局。例如: open [roundname]",
			"加入一个战局。例如: join [roundname]",
			"出招。例如: cast [scissor | paper | rock]",
			"放弃。例如: quit",
			"登出服务器。例如: logout"
	};
	void printUsage(){
		for(String s:usage){
			System.out.println(s);
		}
	}
	Client(String serverip,int port){
		this.serverip=serverip;
		this.port=port;
	}
	InputStream in;
	DataOutputStream out;
	void send(String op,String data) throws IOException{
		byte temp[]=JsonUtil.writeJson(op, data);
		out.writeInt(temp.length);
		out.write(temp);
		//out.flush();
	}
	private void logIn(String data){
		try {
			send("login", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void logOut(String data){
		try {
			send("logout", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void open(String data){
		try {
			send("open", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void join(String data){
		try {
			send("join", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void cast(String data){
		if("scissor".equals(data)||"paper".equals(data)||"rock".equals(data)){
			try {
				send("cast", data);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else
			printUsage();
		
	}
	private void quit(String data){
		try {
			send("quit", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void info(String data){
		try {
			send("info", data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	class AsynPrinter extends Thread{
		InputStream inputStream;

		public AsynPrinter(InputStream inputStream) {
			super();
			this.inputStream = inputStream;
		}
		@Override
		public void run() {
			
			DataInputStream inputStream =new DataInputStream(in);     
	    	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    	byte[] by = new byte[2048];
           	int n;
           	boolean isRun=true;
           	try {
	           	while(isRun){
	           		int size;
					
						size = inputStream.readInt();
					
	           		int cnt=0;
		                while(cnt<size){
		                	n=inputStream.read(by);
		                	if(n!=-1){
		                		cnt+=n;
		                		baos.write(by,0,n);
		                	}	
		                }
						
					 JSONObject json = new JSONObject(baos.toString());
					 
					 baos.reset();
					 System.out.println("<server> : "+json.getString("msg"));
						
			   }	
           	} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
			}
           	System.out.println("connection closed ");
           	System.exit(-1);
		}
	}
	public void go() {
		// TODO Auto-generated method stub
		
		try {
			Socket socket=new Socket(serverip,port);
			in=socket.getInputStream();
			out=new DataOutputStream(socket.getOutputStream());
			Scanner sc=new Scanner(System.in);
			new AsynPrinter(in).start();
			System.out.println("client : welcome");
//			printUsage();
			boolean run=true;
			while(run){
				//printUsage();
				String s[]=sc.nextLine().split(" ");
				
				if(s.length<=2&&s.length>0){
					if(s.length==1){
						switch (s[0]) {
						case "logout":logOut("nothing");break;
						case "quit":quit("nothing");break;
						case "exit":run=false;break;
						default :System.out.println("["+s[0]+"] not recognized");printUsage();
						}
					}else{
						if(s[1].isEmpty()){
							System.out.println("args is not enough");
							printUsage();
						}
						switch (s[0]) {
						case "login":logIn(s[1]);break;
						case "quit":quit(s[1]);break;
						case "open":open(s[1]);break;
						case "join":join(s[1]);break;
						case "cast":cast(s[1]);break;
						case "info":info(s[1]);break;

						default :System.out.println("["+s[0]+"] not a recognized operation");printUsage();
						}
					}
				}
				else {
					System.out.println("error operation. args is too long or too short");
					printUsage();
				}
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("client close");
		System.exit(0);
	}

	public static void main(String[] args) {
		
		System.out.println("client : go");
		Client client;
		if(args.length==2)
			client=new Client(args[0],Integer.valueOf(args[1]));
		else
			client=new Client("127.0.0.1",12345);
		
		client.go();
	}
	
}
